﻿
import pandas as pd
import numpy as np
from plotnine import *
from plotnine.data import *


# 创建示例数据
df = pd.DataFrame({
    'x': range(10),
    'y': range(10),
    'category': ['A', 'B'] * 5
})

# 散点图
p1 = ggplot(df, aes(x='x', y='y')) + geom_point()
print(p1)

# 折线图
p2 = ggplot(df, aes(x='x', y='y')) + geom_line()
print(p2)

# 柱状图
p3 = ggplot(df, aes(x='category', y='y')) + geom_bar(stat='identity')
print(p3)

# 箱线图
p4 = ggplot(df, aes(x='category', y='y')) + geom_boxplot()
print(p4)

# 直方图
p5 = ggplot(df, aes(x='y')) + geom_histogram(bins=5)
print(p5)

# 密度图
p6 = ggplot(df, aes(x='y')) + geom_density()
print(p6)


# 颜色映射
p7 = ggplot(df, aes(x='x', y='y', color='category')) + geom_point(size=3)
print(p7)

# 形状映射
p8 = ggplot(df, aes(x='x', y='y', shape='category')) + geom_point(size=3)
print(p8)

# 大小映射
p9 = ggplot(df, aes(x='x', y='y', size='y')) + geom_point()
print(p9)

# 透明度映射
p10 = ggplot(df, aes(x='x', y='y', alpha='y')) + geom_point(size=5)
print(p10)

# 填充颜色映射
p11 = ggplot(df, aes(x='category', y='y', fill='category')) + geom_bar(stat='identity')
print(p11)


# 颜色标度
p12 = ggplot(df, aes(x='x', y='y', color='category')) + \
    geom_point(size=3) + \
    scale_color_manual(values=['red', 'blue'])
print(p12)

# 连续颜色标度
p13 = ggplot(df, aes(x='x', y='y', color='y')) + \
    geom_point(size=3) + \
    scale_color_gradient(low='blue', high='red')
print(p13)

# x轴标度
p14 = ggplot(df, aes(x='x', y='y')) + \
    geom_point() + \
    scale_x_continuous(breaks=range(0, 10, 2), limits=(0, 10))
print(p14)

# y轴标度
p15 = ggplot(df, aes(x='x', y='y')) + \
    geom_point() + \
    scale_y_log10()
print(p15)

# 创建更多示例数据
df2 = pd.DataFrame({
    'x': range(20),
    'y': range(20),
    'category': ['A', 'B'] * 10,
    'group': ['G1'] * 10 + ['G2'] * 10
})

# 横向分面
p16 = ggplot(df2, aes(x='x', y='y')) + \
    geom_point() + \
    facet_wrap('~ category')
print(p16)

# 网格分面
p17 = ggplot(df2, aes(x='x', y='y')) + \
    geom_point() + \
    facet_grid('group ~ category')
print(p17)

# 自由标度分面
p18 = ggplot(df2, aes(x='x', y='y')) + \
    geom_point() + \
    facet_wrap('~ category', scales='free')
print(p18)

# 内置主题
p19 = ggplot(df, aes(x='x', y='y')) + \
    geom_point() + \
    theme_bw()
print(p19)

p20 = ggplot(df, aes(x='x', y='y')) + \
    geom_point() + \
    theme_minimal()
print(p20)

p21 = ggplot(df, aes(x='x', y='y')) + \
    geom_point() + \
    theme_classic()
print(p21)

# 自定义主题元素
p22 = ggplot(df, aes(x='x', y='y')) + \
    geom_point() + \
    theme(
        axis_text_x=element_text(angle=45, hjust=1),
        panel_grid_major=element_line(color='gray', linetype='dashed'),
        panel_background=element_rect(fill='lightblue')
    )
print(p22)

# 平滑曲线
p23 = ggplot(df, aes(x='x', y='y')) + \
    geom_point() + \
    stat_smooth(method='lm')
print(p23)

# 密度估计
p24 = ggplot(df, aes(x='y')) + \
    stat_density()
print(p24)

# 分位数
p25 = ggplot(df, aes(sample='y')) + \
    stat_qq()
print(p25)

# 极坐标
p26 = ggplot(df, aes(x='category', y='y', fill='category')) + \
    geom_bar(stat='identity') + \
    coord_polar()
print(p26)

# 翻转坐标
p27 = ggplot(df, aes(x='category', y='y')) + \
    geom_bar(stat='identity') + \
    coord_flip()
print(p27)

# 固定纵横比
p28 = ggplot(df, aes(x='x', y='y')) + \
    geom_point() + \
    coord_fixed(ratio=1)
print(p28)

import pandas as pd
import numpy as np
from plotnine import *

# 创建示例数据
np.random.seed(42)
n = 100
df = pd.DataFrame({
    'x': np.random.normal(0, 1, n),
    'y': np.random.normal(0, 1, n),
    'category': np.random.choice(['A', 'B', 'C'], n),
    'value': np.random.uniform(1, 10, n)
})

# 创建综合图形
p = (ggplot(df, aes(x='x', y='y', color='category', size='value'))
     + geom_point(alpha=0.7)
     + stat_smooth(method='lm', se=False, aes(group='category'))
     + facet_wrap('~ category')
     + scale_color_manual(values=['#E69F00', '#56B4E9', '#009E73'])
     + scale_size_continuous(range=(1, 10))
     + labs(
         title='综合示例: 散点图与回归线',
         x='X 变量',
         y='Y 变量',
         color='类别',
         size='值大小'
     )
     + theme_bw()
     + theme(
         plot_title=element_text(size=16, face='bold', hjust=0.5),
         axis_text=element_text(size=10),
         legend_position='right'
     )
)

print(p)

# 保存图形
p.save('plotnine_example.png', dpi=300, width=10, height=6)



# 使用采样或聚合处理大型数据集
df_large = pd.DataFrame({
    'x': np.random.normal(0, 1, 10000),
    'y': np.random.normal(0, 1, 10000),
    'category': np.random.choice(['A', 'B', 'C'], 10000)
})

# 使用六边形分箱
p_hex = ggplot(df_large, aes(x='x', y='y')) + \
    geom_hex(bins=30) + \
    scale_fill_gradient(low='lightblue', high='darkblue')
print(p_hex)

# 创建标注数据
annotations = pd.DataFrame({
    'x': [0],
    'y': [0],
    'label': ['中心点']
})

p_text = ggplot(df, aes(x='x', y='y')) + \
    geom_point() + \
    geom_text(data=annotations, aes(label='label'), color='red', size=10)
print(p_text)

# 使用 plotnine 内置数据集
from plotnine.data import mtcars, diamonds

# 汽车数据集示例
p_mtcars = ggplot(mtcars, aes(x='wt', y='mpg', color='factor(cyl)')) + \
    geom_point() + \
    labs(color='气缸数')
print(p_mtcars)

# 钻石数据集示例
p_diamonds = ggplot(diamonds, aes(x='carat', y='price', color='cut')) + \
    geom_point(alpha=0.1) + \
    scale_x_log10() + \
    scale_y_log10() + \
    facet_wrap('~ cut')
print(p_diamonds)


# 创建自定义几何对象
class geom_custom(geom_point):
    DEFAULT_AES = {'color': 'red', 'size': 3, 'alpha': 1}
    DEFAULT_PARAMS = {'stat': 'identity', 'position': 'identity'}
    
    def draw_layer(self, data, layout, coord, **params):
        # 自定义绘制逻辑
        return super().draw_layer(data, layout, coord, **params)

p_custom = ggplot(df, aes(x='x', y='y')) + geom_custom()
print(p_custom)
